const _kind = Symbol('kind')
const _source = Symbol('source')
const _sender = Symbol('sender')
export type EventKind = 'none' | 'any' | 'rename' | 'add-item'
export interface Event {
  kind: string | number
  source: Event
  sender: Object | Function | null
  [n: string]: any
}
export class EventObject implements Event {
  [_kind]: string | number;
  [_sender]: unknown;
  [_source]: Event
  constructor(kind: string | number, sender: Object, source?: Event) {
    this[_kind] = kind
    this[_sender] = sender
    this[_source] = source ?? this
  }
  get kind(): string | number {
    return this[_kind]
  }
  get sender(): unknown {
    return this[_sender]
  }
  get source(): Event {
    return this[_source]
  }

  public static isEvent(obj: unknown): boolean {
    if (!obj) return false
    if (obj instanceof EventObject) return true
    const kt = typeof (obj as Event).kind
    if (kt != 'string' && kt != 'number') return false
    if ((obj as Event).sender === undefined) return false
    if (typeof (obj as Event).source !== 'object') return false
    return true
  }
  public static make(
    obj: Object,
    kind: string | number,
    sender: Object,
    source?: Event
  ): Event {
    if (!obj) return new EventObject(kind, sender, source)
    const knd = kind ?? (obj as Event).kind
    const sdr = sender ?? (obj as Event).sender
    const src = source ?? (obj as Event).source ?? obj
    Object.defineProperty(obj, 'kind', {
      enumerable: true,
      configurable: false,
      writable: false,
      value: knd,
    })
    Object.defineProperty(obj, 'sender', {
      enumerable: true,
      configurable: false,
      writable: false,
      value: sdr,
    })
    Object.defineProperty(obj, 'source', {
      enumerable: true,
      configurable: false,
      writable: false,
      value: src,
    })
  }
}
export function makeEvent(evt?: Object) {
  //if (!evt) evt =
}
export type EventHandle = (sender: Object, evt: Event) => any

export interface Listening {
  id: string
  kind: string
  description?: string
  handle: EventHandle
}
const _listeners = Symbol('listeners')
